import { createEntity } from '../../database/middleware';
import {
  type EntityOptions,
  listEntitiesPaginated,
  listEntitiesThroughRelationsPaginated,
  loadEntityThroughRelationsPaginated,
  storeLoadById
} from '../../database/middleware-loader';
import type { AuthContext, AuthUser } from '../../types/user';
import type { MalwareAnalysisAddInput, QueryMalwareAnalysesArgs } from '../../generated/graphql';
import { notify } from '../../database/redis';
import { BUS_TOPICS } from '../../config/conf';
import { ABSTRACT_STIX_CYBER_OBSERVABLE, ABSTRACT_STIX_DOMAIN_OBJECT } from '../../schema/general';
import type { DomainFindById } from '../../domain/domainTypes';
import {
  type BasicStoreEntityMalwareAnalysis,
  ENTITY_TYPE_MALWARE_ANALYSIS,
  RELATION_ANALYSIS_SCO,
  RELATION_HOST_VM,
  RELATION_INSTALLED_SOFTWARE,
  RELATION_SAMPLE
} from './malwareAnalysis-types';
import { ENTITY_SOFTWARE } from '../../schema/stixCyberObservable';
import { RELATION_OPERATING_SYSTEM } from '../../schema/stixRefRelationship';
import type { BasicStoreCommon } from '../../types/store';

export const findById: DomainFindById<BasicStoreEntityMalwareAnalysis> = (context: AuthContext, user: AuthUser, malwareAnalysisId: string) => {
  return storeLoadById(context, user, malwareAnalysisId, ENTITY_TYPE_MALWARE_ANALYSIS);
};

export const findAll = (context: AuthContext, user: AuthUser, opts: QueryMalwareAnalysesArgs) => {
  return listEntitiesPaginated<BasicStoreEntityMalwareAnalysis>(context, user, [ENTITY_TYPE_MALWARE_ANALYSIS], opts);
};

export const addMalwareAnalysis = async (context: AuthContext, user: AuthUser, malwareAnalysis: MalwareAnalysisAddInput) => {
  const created = await createEntity(context, user, malwareAnalysis, ENTITY_TYPE_MALWARE_ANALYSIS);
  return notify(BUS_TOPICS[ABSTRACT_STIX_DOMAIN_OBJECT].ADDED_TOPIC, created, user);
};

export const hostVmSoftware = async <T extends BasicStoreCommon> (context: AuthContext, user: AuthUser, malwareAnalysisId: string) => {
  return loadEntityThroughRelationsPaginated<T>(context, user, malwareAnalysisId, RELATION_HOST_VM, ENTITY_SOFTWARE, false);
};

export const operatingSystemSoftware = async <T extends BasicStoreCommon> (context: AuthContext, user: AuthUser, malwareAnalysisId: string) => {
  return loadEntityThroughRelationsPaginated<T>(context, user, malwareAnalysisId, RELATION_OPERATING_SYSTEM, ENTITY_SOFTWARE, false);
};

export const sampleObservable = async <T extends BasicStoreCommon> (context: AuthContext, user: AuthUser, malwareAnalysisId: string) => {
  return loadEntityThroughRelationsPaginated<T>(context, user, malwareAnalysisId, RELATION_SAMPLE, ABSTRACT_STIX_CYBER_OBSERVABLE, false);
};

export const installedSoftwarePaginated = async <T extends BasicStoreCommon> (context: AuthContext, user: AuthUser, attackPatternId: string,
  args: EntityOptions<BasicStoreCommon>) => {
  return listEntitiesThroughRelationsPaginated<T>(context, user, attackPatternId, RELATION_INSTALLED_SOFTWARE, ENTITY_SOFTWARE, false, args);
};

export const analysisScoPaginated = async <T extends BasicStoreCommon> (context: AuthContext, user: AuthUser, attackPatternId: string, args: EntityOptions<BasicStoreCommon>) => {
  return listEntitiesThroughRelationsPaginated<T>(context, user, attackPatternId, RELATION_ANALYSIS_SCO, ABSTRACT_STIX_CYBER_OBSERVABLE, false, args);
};
